home *** CD-ROM | disk | FTP | other *** search
- /*
-
-
- copyright 1993, Alec Russell, All rights reserved
-
-
- read DA/DP lbm, and bbms of type PBM only
-
- 320x200, 256 color, mode 0x13 ONLY
-
- I apologize for the missing function, (gmalloc/gfree/f_read),
- but they are all easy to replace or write.
-
- The memory allocation needs to be cleaned up in this code, but
- it works.
-
- pr2() is used to print debug stuff to a second monitor
- and can be deleted.
-
- */
-
- #pragma inline
-
- #include <stdio.h>
- #include <io.h>
- #include <string.h>
- #include <conio.h>
- #include <dos.h>
-
- #define BYTE unsigned char
- #define ULONG unsigned long
- #define USHORT unsigned short
- typedef char far * FARPTR;
-
-
- char far *gmalloc(USHORT size, char *name);
- char far *gfree(char far *p, char *name);
- void pr2(char *s, ...);
-
- int f_read(int handle, char far *b, USHORT len);
-
- typedef struct
- {
- USHORT width, height;
- BYTE far *bitmap;
- }
- shape_t;
-
-
- typedef struct
- {
- USHORT w,h;
- short x,y;
- char nPlanes;
- char masking;
- char compression;
- char pad1;
- USHORT transparentColor;
- char xAspect,yAspect;
- short pageW,pageH;
- }
- bhmd_t;
-
-
- unsigned char palette[768];
-
- /* alter a far pointer so that the offset is zero,
- handy if the data is actualy 64k long */
- /* ---------------------- normalize() -------------------- March 26,1993 */
- char far *normalize(char far *p)
- {
-
- USHORT seg,off;
-
- seg = FP_SEG(p);
- off = FP_OFF(p);
- seg += (off / 16);
- off &= 0x000f;
- p = MK_FP(seg,off);
-
- return(p);
- }
-
- /* convert motorola type long int to intel type long int */
- long motr2intl(long l)
- {
- return(((l & 0xff000000L) >> 24) +
- ((l & 0x00ff0000L) >> 8) +
- ((l & 0x0000ff00L) << 8) +
- ((l & 0x000000ffL) << 24));
- }
-
- /* convert motorola type int to intel type int */
- short motr2inti(short n)
- {
- return(((n & 0xff00) >> 8) | ((n & 0x00ff) << 8));
- }
-
-
- /* de-compress the run-length encoded data */
- /* ---------------------- de_compress() ------------------ March 23,1993 */
- FARPTR de_compress(BYTE far *buffer, short width, short height)
- {
- unsigned char far *buff, far *p;
- short y;
- USHORT c;
- USHORT i, n;
-
- // gmalloc is the same as farmalloc()
- buff=gmalloc((unsigned long)width*height, "decomp");
- p=buff;
-
- for ( y=0; y < height; y++ )
- {
- n=0;
- do
- {
- c=*buffer++;
- if ( c & 0x80 )
- {
- i = ((~c) & 0xff) + 2;
- c=*buffer++;
- while ( i-- )
- {
- *buff++=c;
- n++;
- }
- }
- else
- {
- i=(c & 0xff)+1;
- while ( i-- )
- {
- *buff++=*buffer++;
- n++;
- }
- }
- }
- while ( n < width );
- }
-
- return(p);
- }
-
-
- /*
- read one lbm, or bbm file created with DA or DP
- MAke sure the stencil, and other option are OFF when a picture
- is saved. If the stencil option is one when the picture is saved, DA will
- save the picture in ILBM format which is PLANED pict data, which this code
- doesn't handle.
- */
- /* ---------------------- read_pbm() --------------------- March 27,1993 */
- short read_pbm(char *fname, shape_t *shape)
- {
- FILE *fp;
- unsigned char *p;
- USHORT i, err=0;
- char b[5], sub_type[5];
- unsigned long l;
- USHORT width, height;
- bhmd_t bhmd;
- unsigned char far *buffer=NULL;
- char far *t1;
- short skipped=0;
-
-
- pr2("Reading: %s", fname);
-
- fp=fopen(fname, "rb");
- if ( fp )
- {
- fread(b, 1,4, fp);
- if ( !memcmp(b, "FORM", 4) )
- {
- pr2("Form type FORM found");
- /* ignore the size */
- fread((char *)&l,1,4,fp);
-
- /* get the subtype */
- fread(sub_type, 1,4, fp);
- if ( !memcmp(sub_type, "PBM ", 4) )
- {
- pr2("sub type %4.4s", sub_type);
-
- /* read all the chunks */
- do {
- fread(b,1,4,fp);
- fread((char *)&l,1,4,fp);
- l=motr2intl(l);
- if(l & 1L)
- ++l;
-
- /* HEADER */
- if ( !memcmp(b, "BMHD", 4) )
- {
- if ( fread(&bhmd, 1, sizeof(bhmd_t), fp) == sizeof(bhmd_t) )
- {
- width=motr2inti(bhmd.w);
- height=motr2inti(bhmd.h);
- pr2("width %d height %d", width, height);
- shape->width=width;
- shape->height=height;
- }
- else
- {
- printf("ERROR reading BHMD\n");
- err=1;
- }
- }
- else
- {
- /* PALETTE */
- if ( !memcmp(b, "CMAP", 4) )
- {
- pr2("got cmap");
- if ( l != 768 )
- {
- printf("Invalid palette\n");
- err=1;
- }
- else
- {
- fread(palette, 1, 768, fp);
- for ( p=palette, i=0; i < 768; i++, p++ )
- *p>>=2;
- }
- }
- else
- {
- /* BITMAP, may be packed */
- if ( !memcmp(b, "BODY", 4) )
- {
- pr2("Got body");
- // gmalloc is the same as farmalloc()
- buffer=gmalloc(64000u, "body");
-
- pr2("read body");
- fseek(fp, 0l, SEEK_CUR); // must do this to sync up the file for
- // the far read, must do if any freads
- // done, as they buffer stuff
- // f_read() reads into a far buffer
- i=f_read(fileno(fp), buffer, (unsigned short)l);
- if ( i != l )
- {
- pr2("l %ld i %u", l, i);
- exit(1);
- }
-
-
- if ( bhmd.compression )
- {
- pr2("de-compressing");
- t1=de_compress(buffer, width, height);
- gfree(buffer, "decomp"); // same as farfree()
- buffer=t1;
- pr2("de-compressed");
- }
-
- }
- else
- {
- /* skip unknown chunk, a very important step */
- *(b + 4)=0;
- // pr2("Skipped chunk type %s", b);
- fseek(fp,l,SEEK_CUR);
- skipped++;
- }
- }
- }
- }
- while ( !ferror(fp) && memcmp(b,"BODY",4) && skipped < 1024 );
-
- }
- else
- {
- printf("Not Brush or Pict, sub-type\n");
- if ( !memcmp(sub_type, "ILBM", 4) )
- {
- printf("%s\n", fname);
- printf("This picture is an ILBM, make sure all\n");
- printf("options, eg stencils, are OFF before saving pict.\n");
- }
-
- err=1;
- }
- }
- else
- {
- printf("Not a brush or pict form\n");
- err=1;
- }
-
-
- fclose(fp);
- }
- else
- {
- printf("ERROR: opening %s\n", fname);
- err=1;
- }
-
- if ( buffer && err )
- {
- gfree(buffer, "body"); // same as farfree()
- buffer=NULL;
- }
-
- shape->bitmap=buffer;
-
- return err;
- }
-
-
- /* ------------------------ end of file ----------------------------- */
-